<template>
    <div class="tree-contaner">
        <a-input-search v-if="sreachAble" v-model:value="searchValue" style="margin-bottom: 8px" placeholder="Search" />
        <a-tree
            class="tree"
            :tree-data="treeData"
            :load-data="onLoadData"
            :replaceFields="{
                children: 'children',
                title: 'label',
                key: 'id',
            }"
            @select="handleSelectNode"
            :style="{ maxHeight: maxHeight + 'px' }"
        >
            <template #title="{ label }">
                <span v-if="label.indexOf(searchValue) > -1">
                    {{ label.substr(0, label.indexOf(searchValue)) }}
                    <span style="color: #f50">{{ searchValue }}</span>
                    {{ label.substr(label.indexOf(searchValue) + searchValue.length) }}
                </span>
                <span v-else>{{ label }}</span>
            </template>
        </a-tree>
    </div>
</template>
<script lang="ts">
import { defineComponent, onMounted, reactive, toRefs, watch } from 'vue';
import useDepts from '@/hooks/useDepts';
import { DeptsQuery } from '@/types/depts';

interface DeptsState {
    treeData: NormalObj[];
    expandedKeys: (string | number)[];
    selectedKeys: (string | number)[];
    searchValue: string;
}

export default defineComponent({
    name: 'tree',
    props: {
        value: {
            type: [String, Number, Array],
        },
        // 是否显示搜索框
        sreachAble: {
            type: Boolean,
            default: () => false,
        },
        // 是否显示checkbox
        checkable: {
            type: Boolean,
            default: () => false,
        },
        maxHeight: {
            type: [Number],
        },
    },
    setup(props, { emit }) {
        const state: DeptsState = reactive({
            treeData: [],
            expandedKeys: [],
            selectedKeys: [],
            searchValue: '',
        });

        onMounted(async () => {
            const params: DeptsQuery = {
                pidIsNull: true,
            };
            let { list } = await useDepts(params);
            state.treeData = list.length
                ? list.map((item) => {
                      return Object.assign({}, item, { isLeaf: item.leaf });
                  })
                : [];
        });

        // 异步加载树节点数据
        const onLoadData = (treeNode: NormalObj) => {
            return new Promise(async (resolve: (value?: unknown) => void) => {
                if (treeNode.dataRef.children) {
                    resolve();
                    return;
                }
                const params: DeptsQuery = {
                    pid: treeNode.eventKey,
                };
                let { list } = await useDepts(params);
                list = list.length
                    ? list.map((item: NormalObj) => {
                          return Object.assign({}, item, { isLeaf: (item as any).leaf });
                      })
                    : [];
                treeNode.dataRef.children = list;
                resolve();
            });
        };
        // 搜索树
        let timer = 0;
        watch(
            () => state.searchValue,
            (newValue) => {
                clearTimeout(timer);
                timer = window.setTimeout(async () => {
                    const params: DeptsQuery = {
                        name: newValue,
                    };
                    let { list } = await useDepts(params);
                    state.treeData = list.length
                        ? list.map((item) => {
                              return Object.assign({}, item, { isLeaf: item.leaf });
                          })
                        : [];
                }, 500);
            }
        );

        // 选择树节点
        const handleSelectNode = (selectedKeys: (string | number)[]) => {
            emit('update:value', selectedKeys);
        };
        return {
            ...toRefs(state),
            handleSelectNode,
            onLoadData,
        };
    },
});
</script>
<style lang="scss" scoped>
.tree-contaner {
    .tree {
        overflow: auto;
    }
}
</style>
